#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>
#include<vector>






// 创建多线程

const int num = 10;

void *routine(void *args)
{
    sleep(1);
    std::string name = static_cast<const char *>(args);
    delete (char*)args;

    int cnt = 5;
    while (cnt--)
    {
        std::cout << "new线程名字: " << name << std::endl;
        sleep(1);
    }
    return nullptr;
}

int main()
{
    // char id[64];
    std::vector<pthread_t> tids;
    for (int i = 0; i < num; i++)
    {
        pthread_t tid;
        // bug?? 
        char *id = new char[64];  //这里一定要自己在堆上进行区域的划分，因为如果不是在堆上进行区域的划分，那么此时在栈上开辟空间的话，那么在上面线程等待的过程中，就会有新的数据流入，把之前的覆盖
        snprintf(id, 64, "thread-%d", i);
        int n = pthread_create(&tid, nullptr, routine, id);
        if (n == 0)
            tids.push_back(tid);
        else
            continue;
    }

    for (int i = 0; i < num; i++)
    {
        // 一个一个的等待
        int n = pthread_join(tids[i], nullptr);
        if (n == 0)
        {
            std::cout << "等待新线程成功" << std::endl;
        }
    }

    return 0;
}














// void *tieshi(void *argc)
// {
//     std ::string name = static_cast<char *>(argc);
//     int count = 20;
//     while (count--)
//     {
//         std ::cout << name << std ::endl;
//         sleep(1);
//     }
//     return nullptr;
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, tieshi, (void *)"thread -1");
//     pthread_join(tid, nullptr); //如果没有这句话的话，上面的循环就不会执行，因为此时主线程已经结束了（新线程在进行的同时，主线程也会向后进行），所以此时直接结束了
//     return 0;
// }

// // 1. main函数结束，代表主线程结束，一般也代表进程结束
// // 2. 新线程对应的入口函数，运行结束，代表当前线程运行结束

// // 3. 一个问题：给线程传递的参数和返回值，可以是任意类型(包括对象)
// // 如果主线程不想再关心新线程，而是当新线程结束的时候，让他自己释放？？
// // 设置新线程为分离状态
// // 技术层面:  线程默认是需要被等待的，joinable。如果不想让主线程等待新线程
// // 想让新线程结束之后，自己退出，设置为分离状态(!joinable or detach)  // TODO
// // 理解层面：线程分离，主分离新，新把自己分离。
// // 分离的线程，依旧在进程的地址空间中，进程的所有资源，被分离的线程，依旧可以访问，可以操作。
// // 主不等待新线程。
// // 分离操作
// // 如果线程被设置为分离状态，不需要进行join，join会失败！！
// class Task
// {
// public:
//     Task(int a,int b) : _a(a),_b(b){}
//     int Excute()
//     {
//         return _a + _b;
//     }
//     ~Task() {};
// private:
//     int _a;
//     int _b;
// };

// class Result
// {
// public:
//     Result(int resurt) : _resurt(resurt) {}
//     int ReturnResurt() {return _resurt;}
//     ~Result() {}
// private:
//     int _resurt;
// };

// void* tishi(void* argc)
// {
//     Task* t = static_cast<Task*>(argc);
//     sleep(1);
//     Result* ret = new Result(t -> Excute());
//     return ret;
// }

// int main()
// {
//     pthread_t tid;
//     Task* s1 = new Task(1,2);
//     pthread_create(&tid,nullptr,tishi,s1);  //这里说明此时最后面那个参数可以是正常变量，也可以是一个对象（类类型的）
//     Result* ret = nullptr; //虽然是空的，但其实系统自己给他开辟了8kb的空间（32位下指针长度为8kb）
//     pthread_join(tid,(void**)&ret);
//     int n = ret ->ReturnResurt();
//     // sleep(1);
//     std :: cout << "新线程结束，它的运行结果是：" << n << std :: endl;
//     return 0;
// }

// void* routine(void* argc)
// {
//     std :: string name = (char*) argc;
//     int count = 10;
//     while(count--)
//     {
//         sleep(1);
//         std :: cout << "我是一个新的线程，我的名字是：" << name << std :: endl;
//     }
//     return nullptr;
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid,nullptr,routine,(void*)"tgread-l");  //最后一个可以是一个结构体
//     int count = 10;
//     while(count--)
//     {
//         sleep(1);
//         std :: cout << "我是一个主线程，我的名字是：" << std :: endl;
//     }
//     pthread_join(tid,nullptr);
//     return 0;
// }